Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

token based report #6216

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open

token based report #6216

wants to merge 10 commits into from

Conversation

pjain1
Copy link
Member

@pjain1 pjain1 commented Dec 5, 2024

Changes:

  • This PR changes all the report links to always have a magic token.
  • Magic tokens are created for each run of the report with expiry of 60 days for both internal and external users.
  • This enables the links to never expire and everytime its clicked it just works (if user is removed or added etc. in all scenarios) unless the token expires.

UI changes needed:

  • Report Creation API - Since even external users can now open the report in explore, the API now expects either the metrics view and explore name or canvas name on which report is created.
  • Open link - handle token and use it show the explore (similar to a public URL). If a user is logged in, it should display a banner to say "this is a preview link" or something like that (may need product input here). The report's token may have different permissions/attributes than the current user (e.g. if the report was created by an admin, but the recipient is not an admin), so it cannot simply show the dashboard as the current user.
  • Download link - use token to enable download, it already happens for external user now so probably only removing internal download page (if exists).
  • Unsubscribe link - It will need to grab the email or slack_user query param from the url and call the unsubscribe API with this param.

Important Note: This does not support locking time ranges as of now (locking dimension filter works), as they would be evaluated during each report run at runtime. The queries that are sent by explore have a separate time range apart from the filter, magic token only supports row filter. If mgc token has time range then it will need to be reconciled with the actual time range sent.

Contributes to https://github.com/orgs/rilldata/projects/38/views/8?pane=issue&itemId=85181742&issue=rilldata%7Crill-private-issues%7C855

@pjain1 pjain1 marked this pull request as draft December 5, 2024 11:22
@pjain1 pjain1 requested a review from begelundmuller December 9, 2024 15:42
@pjain1 pjain1 marked this pull request as ready for review December 9, 2024 15:43
Copy link
Contributor

@begelundmuller begelundmuller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, do we have a job that clears expired magic auth tokens periodically? If not, can you add one?

admin/database/database.go Outdated Show resolved Hide resolved
admin/server/reports.go Outdated Show resolved Hide resolved
admin/server/reports.go Outdated Show resolved Hide resolved
admin/server/reports.go Outdated Show resolved Hide resolved
admin/server/reports.go Outdated Show resolved Hide resolved
admin/server/reports.go Outdated Show resolved Hide resolved
proto/rill/admin/v1/api.proto Outdated Show resolved Hide resolved
@pjain1
Copy link
Member Author

pjain1 commented Dec 16, 2024

Also, do we have a job that clears expired magic auth tokens periodically? If not, can you add one?

There is already a deleteExpiredAuthTokens job that will take care of it since we set an expiry.

@begelundmuller
Copy link
Contributor

begelundmuller commented Dec 27, 2024

@pjain1 I responded to the two open questions on this PR. Can you let me know when you address them (or if you decide they are not worth it) and fix the merge conflict?

Comment on lines +666 to 669
type ResourceName struct {
Type string
Name string
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably use snake case for JSON field names:

Suggested change
type ResourceName struct {
Type string
Name string
}
type ResourceName struct {
Type string `json:"type"`
Name string `json:"name"`
}

Comment on lines +6 to +7
'Type', resource_type,
'Name', resource_name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Snake case:

Suggested change
'Type', resource_type,
'Name', resource_name
'type', resource_type,
'name', resource_name

Comment on lines 686 to +691
FilterJSON string
Fields []string
State string
DisplayName string
Internal bool
Resources []ResourceName
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: logically it feels like Resources should be placed here, like ResourceType and ResourceName were before:

Suggested change
FilterJSON string
Fields []string
State string
DisplayName string
Internal bool
Resources []ResourceName
Resources []ResourceName
FilterJSON string
Fields []string
State string
DisplayName string
Internal bool

Comment on lines 299 to +303
Filter: filter,
Fields: tkn.Fields,
State: tkn.State,
DisplayName: tkn.DisplayName,
Resources: rs,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same nit:

Suggested change
Filter: filter,
Fields: tkn.Fields,
State: tkn.State,
DisplayName: tkn.DisplayName,
Resources: rs,
Resources: rs,
Filter: filter,
Fields: tkn.Fields,
State: tkn.State,
DisplayName: tkn.DisplayName,

}

externalUrls := make(map[string]*adminv1.GetReportMetaResponse_URLs, len(externalEmails))
emailTokens, err := s.reconcileMagicTokensForExternalEmails(ctx, proj.OrganizationID, proj.ID, req.Report, req.OwnerId, externalEmails)
tokens, ownerEmail, err := s.createMagicTokens(ctx, proj.OrganizationID, proj.ID, req.Report, req.OwnerId, recipients, req.Resources)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a filter was applied to the report then that doesn't get propagated to the magic auth token here – so in theory, people can explore more data than that which the report filters by. Is that right? This is probably desirable in many cases, but not necessarily for external partners.

I wonder if we should perhaps add a flag to the report YAML and CreateReport API for whether or not to generate an open URL or only an export URL. E.g. it could be named open_mode: none|full (and then we could add support for a filtered mode later)

Comment on lines +490 to +494
if opts.Explore != "" && opts.Canvas != "" {
return nil, fmt.Errorf("cannot set both explore and canvas")
}
res.Annotations.Explore = opts.Explore
res.Annotations.Canvas = opts.Canvas
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we check somewhere if the report has an explore or canvas? And if not, then skip generating the open link (since it would not actually work).

Some legacy reports and YAML-managed reports may not have an explore or canvas.

Comment on lines +1762 to +1763
// list of resources to grant access to.
repeated ResourceName resources = 11;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: move up above resource_type and resource_name

@@ -49,13 +47,19 @@ func (s *Server) IssueMagicAuthToken(ctx context.Context, req *adminv1.IssueMagi
return nil, status.Error(codes.PermissionDenied, "not allowed to create a magic auth token")
}

resources := make([]database.ResourceName, len(req.Resources))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like it's missing backwards compatibiltiy for req.ResourceType and req.ResourceName? (Can be fixed by adding them to req.Resources if they are not empty)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants